package tw.edu.tku.im.maze.database;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONObject;

import tw.edu.tku.im.maze.MazeMap;
import tw.edu.tku.im.maze.Member;
import tw.edu.tku.im.maze.Packet;
import tw.edu.tku.im.maze.RegisterRep;
import tw.edu.tku.im.maze.Room;
import tw.edu.tku.im.maze.UpdateRoomRep;
import tw.edu.tku.im.maze.UpdateRoomReq;

public class UpdateRoomProcessor extends PacketProcessor {

   @Override
   String acceptName() {
      return "updateRoom";
   }
   
   private Member[] getMember(int roomID, int teamNumber) {
      try {
         Connection cons = DriverManager.getConnection(address,user,passwd);
         cons.setCatalog(database);
         CallableStatement cstmts = 
               cons.prepareCall("{ call usp_getRoomMember(?,?) }");
         cstmts.setInt(1, roomID);
         cstmts.setInt(2, teamNumber);
         cstmts.execute();
         ResultSet rs = cstmts.getResultSet();
         List<Member> tmp = new ArrayList<Member>();
         while(rs.next()) {
            String userID = rs.getString("userID").trim();
            String username = rs.getString("username").trim();
            tmp.add(new Member(userID, username));
         }
         if(tmp.size()==0) { return null; }
         Member[] ans = new Member[tmp.size()];
         tmp.toArray(ans);
         return ans;
      } catch (SQLException e) {
         e.printStackTrace();
      }
      return null;
   }
   
   private MazeMap getMap(int roomID) {
      try {
         Connection con = DriverManager.getConnection(address,user,passwd);
         con.setCatalog(database);
         CallableStatement cstmt = 
               con.prepareCall("{call usp_getMazeMap(?,?)}");
         cstmt.setInt(1, roomID);
         cstmt.registerOutParameter(2, Types.LONGVARCHAR);
         cstmt.execute();
         Reader mapReader = cstmt.getCharacterStream(2);
         BufferedReader bf = new BufferedReader(mapReader);
//         StringBuilder mapString = new StringBuilder();
//         int ch = 0;
//         int count = 0;
//         while((ch=mapReader.read())!=-1) {
//            System.out.print((char)ch);
//            count++;
//         }
//         System.out.println();
//         System.out.println(count++);
         String mapString = bf.readLine();
//         System.out.println(mapString.length());
         return MazeMap.parse(new JSONObject(mapString));
      } catch (SQLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
      return null;
   }

   @Override
   Packet process(Packet packet) {
    UpdateRoomReq req = (UpdateRoomReq)packet;
    int roomID = req.getRoomID();
    UpdateRoomRep rep;
    try {
       Connection con = DriverManager.getConnection(address,user,passwd);
       con.setCatalog(database);
       CallableStatement cstmt = 
             con.prepareCall("{call usp_getRoomInfo(?,?,?,?,?)}");
       cstmt.setInt(1, roomID);
       cstmt.registerOutParameter(2, Types.TINYINT);
       cstmt.registerOutParameter(3, Types.TINYINT);
       cstmt.registerOutParameter(4, Types.CHAR);
       cstmt.registerOutParameter(5, Types.TINYINT);
       cstmt.execute();
       int roomMode = cstmt.getInt(2);
       int roomState = cstmt.getInt(3);
       String roomName = cstmt.getString(4).trim();
       int mapLv = cstmt.getInt(5);
       
       Member[] teamOne = getMember(roomID, 1);
       
       boolean roomSurvive = true;
       if(roomState==1) {
          roomSurvive = false;
       }
       MazeMap map = null;
       boolean start = false;
       if(roomState==2) {
          start = true;
          map = getMap(roomID);
       }       
       if(roomMode==1) {
          Member[] teamTwo = getMember(req.getRoomID(), 2);
          return new UpdateRoomRep(roomSurvive, roomName, mapLv, 
                                   teamOne, teamTwo, start, map);
       }
       return new UpdateRoomRep(roomSurvive, roomName, mapLv, 
                                teamOne, start, map);
    } catch (SQLException e) {
       e.printStackTrace();
    }
    //...... to do something
//    Member[] members = new Member[] { new Member("john1022", "john"), 
//                                      new Member("mike0908", "mike")};
//    long[] arr = {7, 9, 10, 4, 5, 6, 1, 3};
//    MazeMap map = new MazeMap(arr, 3, 3, 180);
//    UpdateRoomRep rep = new UpdateRoomRep(true, members, false, map);
//    return rep;
    return null;
   }

}
